<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>人生三万天|Life is thirty thousand days</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            background: #1a1a2e;
            min-height: 100vh;
            display: flex;
            flex-direction: column;
            align-items: center;
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            overflow-x: hidden;
            color: white;
        }

        .header {
            font-size: 2.5rem;
            font-weight: bold;
            margin: 2rem 0;
            color: #3498db;
            text-shadow: 0 0 10px rgba(52, 152, 219, 0.5);
        }

        .controls {
            margin: 20px;
            text-align: center;
            z-index: 2;
            position: relative;
            background: rgba(0, 0, 0, 0.3);
            padding: 20px;
            border-radius: 12px;
            backdrop-filter: blur(10px);
        }

        .input-group {
            margin: 10px;
            display: flex;
            gap: 15px;
            align-items: center;
            justify-content: center;
            flex-wrap: wrap;
        }

        .options-group {
            margin: 10px;
            display: flex;
            gap: 20px;
            align-items: center;
            justify-content: center;
            flex-wrap: wrap;
        }

        .option-label {
            display: flex;
            align-items: center;
            gap: 8px;
            color: white;
            cursor: pointer;
        }

        .option-label input[type="checkbox"] {
            width: 18px;
            height: 18px;
            cursor: pointer;
        }

        input, select {
            padding: 10px 15px;
            border-radius: 8px;
            border: 2px solid transparent;
            background: #2c3e50;
            color: white;
            width: 200px;
            font-size: 16px;
            transition: all 0.3s ease;
        }

        .legend {
            position: fixed;
            top: 50%;
            right: 20px;
            transform: translateY(-50%);
            background: rgba(0, 0, 0, 0.9);
            padding: 20px;
            border-radius: 12px;
            color: white;
            font-size: 14px;
            backdrop-filter: blur(10px);
            z-index: 1000;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
            display: none;
            max-height: 80vh;
            overflow-y: auto;
        }

        .legend-title {
            font-size: 16px;
            font-weight: bold;
            margin-bottom: 15px;
            text-align: center;
        }

        .legend-item {
            display: flex;
            align-items: center;
            margin: 8px 0;
            gap: 10px;
        }

        .legend-color {
            width: 20px;
            height: 20px;
            border-radius: 4px;
        }

        .legend-close {
            position: absolute;
            top: 10px;
            right: 10px;
            background: none;
            border: none;
            color: white;
            cursor: pointer;
            font-size: 20px;
            padding: 0;
            width: 24px;
            height: 24px;
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 50%;
            transition: background-color 0.3s;
        }

        .legend-close:hover {
            background: rgba(255, 255, 255, 0.1);
        }

        input:focus, select:focus {
            outline: none;
            border-color: #3498db;
            box-shadow: 0 0 10px rgba(52, 152, 219, 0.5);
        }

        input:invalid {
            border-color: #e74c3c;
        }

        button {
            padding: 10px 25px;
            background: #3498db;
            border: none;
            border-radius: 8px;
            color: white;
            cursor: pointer;
            transition: all 0.3s ease;
            font-size: 16px;
            z-index: 2;
        }

        button:hover {
            background: #2980b9;
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(52, 152, 219, 0.4);
        }

        button:active {
            transform: translateY(0);
        }

        .stats {
            position: fixed;
            top: 20px;
            right: 20px;
            background: rgba(0, 0, 0, 0.8);
            padding: 15px 25px;
            border-radius: 12px;
            color: white;
            font-size: 18px;
            backdrop-filter: blur(10px);
            z-index: 2;
            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
        }

        .canvas-container {
            position: relative;
            width: 98%;
            height: calc(100vh - 220px);
            min-height: 400px;
            margin: 20px auto;
            box-shadow: 0 0 30px rgba(0, 150, 255, 0.4);
            border-radius: 15px;
            background: rgba(0, 0, 0, 0.3);
            overflow: hidden; /* 隐藏溢出内容，不使用滚动条 */
            cursor: grab; /* 显示抓手光标，表示可拖动 */
            touch-action: none; /* 防止触摸设备上的默认行为 */
        }

        .canvas-container:active {
            cursor: grabbing; /* 拖动时显示抓取光标 */
        }

        .canvas-wrapper {
            position: absolute;
            transition: transform 0.1s ease-out; /* 平滑的拖动效果 */
            image-rendering: -webkit-optimize-contrast; /* 优化Chrome/Safari的图像渲染 */
            image-rendering: crisp-edges; /* 优化Firefox的图像渲染 */
            image-rendering: pixelated; /* 优化高缩放级别下的像素图形 */
            transform-origin: 0 0;
            will-change: transform; /* 提示浏览器优化变换性能 */
        }

        canvas {
            display: block;
            image-rendering: -webkit-optimize-contrast;
            image-rendering: crisp-edges;
            image-rendering: pixelated;
            backface-visibility: hidden; /* 减少模糊 */
        }

        .navigation-hint {
            position: absolute;
            bottom: 15px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(52, 152, 219, 0.8);
            padding: 8px 15px;
            border-radius: 20px;
            font-size: 14px;
            color: white;
            opacity: 0;
            transition: opacity 0.5s ease;
            pointer-events: none;
            z-index: 10;
            text-align: center;
            white-space: nowrap;
        }

        .canvas-container:hover .navigation-hint {
            opacity: 1;
        }

        .zoom-controls {
            position: absolute;
            top: 10px;
            right: 10px;
            display: flex;
            gap: 5px;
            z-index: 10;
        }

        .zoom-btn {
            width: 30px;
            height: 30px;
            border-radius: 50%;
            background: rgba(52, 152, 219, 0.8);
            color: white;
            border: none;
            font-size: 18px;
            cursor: pointer;
            display: flex;
            justify-content: center;
            align-items: center;
        }

        .zoom-btn:hover {
            background: rgba(52, 152, 219, 1);
        }

        #canvas {
            background: rgba(0, 0, 0, 0.8);
            border-radius: 15px;
            display: block;
        }

        .tooltip {
            position: absolute;
            background: rgba(0, 0, 0, 0.95);
            color: #fff;
            padding: 12px 18px;
            border-radius: 8px;
            pointer-events: none;
            font-size: 14px;
            opacity: 0;
            transition: opacity 0.2s ease;
            transform: translate(-50%, -120%);
            backdrop-filter: blur(5px);
            white-space: nowrap;
            box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
            z-index: 3;
            line-height: 1.5;
        }

        .error-message {
            color: #e74c3c;
            font-size: 14px;
            margin-top: 5px;
            display: none;
        }

        @media (max-width: 768px) {
            .header {
                font-size: 2rem;
                margin: 1rem 0;
            }

            .input-group {
                flex-direction: column;
                gap: 10px;
            }

            .stats {
                position: static;
                margin: 20px;
                width: 90%;
            }

            input, select, button {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <h1 class="header" aria-label="人生进度可视化工具" id="headerTitle">人生进度</h1>
    <div class="controls" role="form" aria-label="进度计算控制面板">
        <div class="input-group">
            <button id="toggleLanguage" aria-label="切换语言">English</button>
        </div>
        <div class="input-group">
            <select id="inputType" aria-label="选择输入类型">
                <option value="age">输入当前年龄</option>
                <option value="birthdate">输入出生日期</option>
            </select>
            <input type="number" id="ageInput" placeholder="输入年龄" min="0" max="120" aria-label="年龄输入框">
            <input type="date" id="birthdateInput" aria-label="出生日期输入框">
            <div class="error-message" id="errorMessage"></div>
            <button id="generateBtn" aria-label="生成进度图表">生成进度</button>
        </div>
        <div class="options-group">
            <label class="option-label">
                <input type="checkbox" id="showEvents" checked aria-label="显示生命节点">
                显示生命节点
            </label>
            <button id="showLegendBtn" aria-label="显示图例">显示图例</button>
        </div>
    </div>
    <div class="stats" role="region" aria-label="统计信息">
        <div>总天数: <span id="total">0</span></div>
        <div>已过天数: <span id="passed">0</span></div>
        <div>剩余天数: <span id="remaining">0</span></div>
    </div>
    
    <div class="legend" id="legend" role="dialog" aria-label="图例">
        <button class="legend-close" id="closeLegend" aria-label="关闭图例">&times;</button>
        <div class="legend-title">人生节点图例</div>
        <div id="legendContent"></div>
    </div>
    <div class="canvas-container" role="img" aria-label="人生进度可视化图表">
        <div class="canvas-wrapper" id="canvasWrapper">
            <canvas id="canvas"></canvas>
        </div>
        <div class="zoom-controls">
            <button class="zoom-btn" id="zoomIn" aria-label="放大">+</button>
            <button class="zoom-btn" id="zoomOut" aria-label="缩小">-</button>
            <button class="zoom-btn" id="zoomReset" aria-label="重置缩放">↺</button>
        </div>
        <div class="navigation-hint">拖动查看 · 滚轮缩放 · 双击重置</div>
        <div class="tooltip" id="tooltip" role="tooltip"></div>
    </div>

    <script>
        document.addEventListener('DOMContentLoaded', () => {
            console.log("DOM内容已加载，开始初始化...");
            
            // 多语言文本对象
            const translations = {
                'zh': {
                    'header': '人生进度',
                    'toggleLanguage': 'English',
                    'inputTypeOptions': [
                        { value: 'age', text: '输入当前年龄' },
                        { value: 'birthdate', text: '输入出生日期' }
                    ],
                    'agePlaceholder': '输入年龄',
                    'generateBtn': '生成进度',
                    'showEvents': '显示生命节点',
                    'showLegend': '显示图例',
                    'stats': ['总天数', '已过天数', '剩余天数'],
                    'legendTitle': '人生节点图例',
                    'legendItems': [
                        { label: '已过天数', description: '你已经度过的日子' },
                        { label: '剩余天数', description: '你未来的日子' },
                        { label: '十年标记', description: '每十年的起点' }
                    ],
                    'lifeEvents': [
                        { age: 0, label: '出生', description: '人生的起点' },
                        { age: 6, label: '入学', description: '开始接受教育' },
                        { age: 18, label: '成年', description: '法律上成为成年人' },
                        { age: 22, label: '毕业', description: '完成学业，步入社会' },
                        { age: 30, label: '而立', description: '事业有成，开始稳定' },
                        { age: 40, label: '不惑', description: '不再迷惑，明确方向' },
                        { age: 50, label: '知天命', description: '了解自己的使命' },
                        { age: 60, label: '花甲', description: '人生的一个轮回' },
                        { age: 70, label: '古稀', description: '享受晚年生活' },
                        { age: 80, label: '耄耋', description: '长寿的象征' },
                        { age: 90, label: '鲐背', description: '高龄的祝福' },
                        { age: 100, label: '期颐', description: '百年人生的成就' }
                    ]
                },
                'en': {
                    'header': 'Life\'s Chapter',
                    'toggleLanguage': '中文',
                    'inputTypeOptions': [
                        { value: 'age', text: 'Enter current age' },
                        { value: 'birthdate', text: 'Enter birth date' }
                    ],
                    'agePlaceholder': 'Enter age',
                    'generateBtn': 'Generate',
                    'showEvents': 'Show life events',
                    'showLegend': 'Show legend',
                    'stats': ['Total days', 'Days passed', 'Days remaining'],
                    'legendTitle': 'Life Events Legend',
                    'legendItems': [
                        { label: 'Days passed', description: 'Days you have lived' },
                        { label: 'Days remaining', description: 'Days in your future' },
                        { label: 'Decade marker', description: 'Start of each decade' }
                    ],
                    'lifeEvents': [
                        { age: 0, label: 'Birth', description: 'Beginning of life' },
                        { age: 6, label: 'School', description: 'Start education' },
                        { age: 18, label: 'Adult', description: 'Legally an adult' },
                        { age: 22, label: 'Graduate', description: 'Complete education' },
                        { age: 30, label: 'Established', description: 'Career stability' },
                        { age: 40, label: 'Midlife', description: 'Clear direction' },
                        { age: 50, label: 'Wisdom', description: 'Know your purpose' },
                        { age: 60, label: 'Retirement', description: 'Life cycle' },
                        { age: 70, label: 'Golden Years', description: 'Enjoy life' },
                        { age: 80, label: 'Longevity', description: 'Symbol of long life' },
                        { age: 90, label: 'Nonagenarian', description: 'Blessing of age' },
                        { age: 100, label: 'Centenarian', description: 'Achievement' }
                    ]
                }
            };

            let currentLanguage = 'zh';
            const daysInLife = 30000;
            let CELL_SIZE; // 动态计算单元格尺寸
            const canvas = document.getElementById('canvas');
            const ctx = canvas.getContext('2d');
            const tooltip = document.getElementById('tooltip');
            const errorMessage = document.getElementById('errorMessage');
            const inputType = document.getElementById('inputType');
            const ageInput = document.getElementById('ageInput');
            const birthdateInput = document.getElementById('birthdateInput');

            // 计算最佳单元格尺寸和画布尺寸
            function calculateOptimalSize() {
                // 计算可用空间
                const container = document.querySelector('.canvas-container');
                const containerWidth = container.clientWidth;
                const containerHeight = container.clientHeight;
                const pixelRatio = window.devicePixelRatio || 1;

                // 计算网格布局
                const aspectRatio = containerWidth / containerHeight;
                const rows = Math.floor(Math.sqrt(daysInLife / aspectRatio));
                const columns = Math.ceil(daysInLife / rows);

                // 计算单元格大小
                const cellByWidth = (containerWidth * 0.95) / columns;
                const cellByHeight = (containerHeight * 0.95) / rows;
                CELL_SIZE = Math.floor(Math.min(cellByWidth, cellByHeight));

                // 确保单元格尺寸不会太小
                CELL_SIZE = Math.max(CELL_SIZE, 4);

                return {
                    width: columns * CELL_SIZE * pixelRatio,
                    height: rows * CELL_SIZE * pixelRatio,
                    displayWidth: columns * CELL_SIZE,
                    displayHeight: rows * CELL_SIZE,
                    rows,
                    columns,
                    pixelRatio
                };
            }

            // 初始化画布尺寸
            function initCanvas() {
                const { width, height, displayWidth, displayHeight, pixelRatio } = calculateOptimalSize();
                
                // 设置画布内部尺寸
                canvas.width = width;
                canvas.height = height;
                
                // 设置画布显示尺寸
                canvas.style.width = `${displayWidth}px`;
                canvas.style.height = `${displayHeight}px`;
                
                // 重置视图状态
                zoomLevel = 1;
                panX = 0;
                panY = 0;
                applyTransform();
                
                // 安全读取已过天数并绘制初始网格
                const passedElement = document.getElementById('passed');
                const passedText = passedElement?.textContent?.replace(/,/g, '') || '0';
                const passed = parseInt(passedText) || 0;
                drawGrid(passed);
            }

            // 初始化输入框显示状态
            function updateInputVisibility() {
                const isAgeType = inputType.value === 'age';
                ageInput.style.display = isAgeType ? 'block' : 'none';
                birthdateInput.style.display = isAgeType ? 'none' : 'block';
                errorMessage.style.display = 'none';
                errorMessage.textContent = '';
            }

            // 验证输入
            function validateInput() {
                if (inputType.value === 'age') {
                    const age = parseFloat(ageInput.value);
                    if (isNaN(age) || age < 0 || age > 120) {
                        showError('请输入0-120之间的有效年龄');
                        return false;
                    }
                } else {
                    const birthDate = new Date(birthdateInput.value);
                    const today = new Date();
                    if (isNaN(birthDate.getTime()) || birthDate > today) {
                        showError('请输入有效的出生日期（不能晚于今天）');
                        return false;
                    }
                }
                return true;
            }

            // 显示错误信息
            function showError(message) {
                errorMessage.textContent = message;
                errorMessage.style.display = 'block';
            }

            // 计算有效天数
            const calculateValidDays = (inputType, value) => {
                if (!value) return 0;
                if (inputType === 'age') {
                    const age = parseFloat(value);
                    return isNaN(age) ? 0 : Math.floor(age * 365.25);
                }
                return 0;
            };

            // 计算出生日期到现在的天数
            const calculatePassedDays = (birthDate) => {
                const today = new Date();
                const birth = new Date(birthDate);
                
                if (birth > today || isNaN(birth.getTime())) return 0;
                return Math.floor((today - birth) / (1000 * 60 * 60 * 24));
            };
            
            // 计算预期寿命
            const calculateLifeExpectancy = () => {
                // 这里可以根据性别、地区等因素计算预期寿命
                // 目前简单返回30000天（约82年）
                return daysInLife;
            };

            // 定义重要的生命节点
            const lifeEvents = [
                { age: 0, label: '出生', color: '#e74c3c', description: '人生的起点' },
                { age: 6, label: '入学', color: '#9b59b6', description: '开始接受教育' },
                { age: 18, label: '成年', color: '#f39c12', description: '法律上成为成年人' },
                { age: 22, label: '毕业', color: '#27ae60', description: '完成学业，步入社会' },
                { age: 30, label: '而立', color: '#16a085', description: '事业有成，开始稳定' },
                { age: 40, label: '不惑', color: '#2980b9', description: '不再迷惑，明确方向' },
                { age: 50, label: '知天命', color: '#8e44ad', description: '了解自己的使命' },
                { age: 60, label: '花甲', color: '#c0392b', description: '人生的一个轮回' },
                { age: 70, label: '古稀', color: '#d35400', description: '享受晚年生活' },
                { age: 80, label: '耄耋', color: '#7f8c8d', description: '长寿的象征' },
                { age: 90, label: '鲐背', color: '#2c3e50', description: '高龄的祝福' },
                { age: 100, label: '期颐', color: '#1abc9c', description: '百年人生的成就' }
            ];
            
            // 生成图例内容
            function generateLegend() {
                const legendContent = document.getElementById('legendContent');
                legendContent.innerHTML = '';
                
                // 添加基本颜色说明
                const basicColors = [
                    { label: '已过天数', color: '#3498db', description: '你已经度过的日子' },
                    { label: '剩余天数', color: '#7f8c8d', description: '你未来的日子' },
                    { label: '十年标记', color: '#e74c3c', description: '每十年的起点' }
                ];
                
                basicColors.forEach(item => {
                    const legendItem = document.createElement('div');
                    legendItem.className = 'legend-item';
                    legendItem.innerHTML = `
                        <div class="legend-color" style="background-color: ${item.color}"></div>
                        <div>
                            <strong>${item.label}</strong>
                            <div>${item.description}</div>
                        </div>
                    `;
                    legendContent.appendChild(legendItem);
                });
                
                // 添加分隔线
                const divider = document.createElement('hr');
                divider.style.margin = '15px 0';
                divider.style.border = '0';
                divider.style.borderTop = '1px solid rgba(255, 255, 255, 0.2)';
                legendContent.appendChild(divider);
                
                // 添加生命节点说明
                const eventsTitle = document.createElement('div');
                eventsTitle.style.fontWeight = 'bold';
                eventsTitle.style.margin = '10px 0';
                eventsTitle.textContent = '生命节点:';
                legendContent.appendChild(eventsTitle);
                
                lifeEvents.forEach(event => {
                    const legendItem = document.createElement('div');
                    legendItem.className = 'legend-item';
                    legendItem.innerHTML = `
                        <div class="legend-color" style="background-color: ${event.color}"></div>
                        <div>
                            <strong>${event.age}岁 - ${event.label}</strong>
                            <div>${event.description}</div>
                        </div>
                    `;
                    legendContent.appendChild(legendItem);
                });
            }

            // 优化的网格绘制函数
            const drawGrid = (passed) => {
                console.log("开始绘制网格, 已过天数:", passed);
                
                const { pixelRatio, displayWidth, displayHeight } = calculateOptimalSize();
                console.log("画布尺寸:", displayWidth, "x", displayHeight, "像素比:", pixelRatio);
                
                ctx.save();
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                
                // 使用离屏canvas优化性能
                console.log("创建离屏Canvas:", canvas.width, "x", canvas.height);
                
                const offscreenCanvas = new OffscreenCanvas(canvas.width, canvas.height);
                const offscreenCtx = offscreenCanvas.getContext('2d', { 
                    alpha: true
                });
                
                console.log("离屏Canvas创建成功");
                
                // 根据缩放级别调整绘制质量
                const isHighQuality = zoomLevel > 2;
                offscreenCtx.scale(pixelRatio, pixelRatio);
                offscreenCtx.imageSmoothingEnabled = !isHighQuality;
                
                console.log("开始绘制网格元素...");
                
                // 获取网格布局信息
                const { rows, columns } = calculateOptimalSize();
                
                // 绘制背景
                offscreenCtx.fillStyle = 'rgba(44, 62, 80, 0.9)';
                offscreenCtx.fillRect(0, 0, displayWidth, displayHeight);

                // 计算有效进度
                const validPassed = Math.min(Math.max(passed, 0), daysInLife);
                
                // 检查是否显示生命节点
                const showEvents = document.getElementById('showEvents').checked;
                
                // 预计算生命节点对应的天数
                const eventDays = showEvents ? lifeEvents.map(event => Math.floor(event.age * 365.25)) : [];
                
                // 绘制网格和填充颜色
                for (let day = 0; day < daysInLife; day++) {
                    const row = Math.floor(day / columns);
                    const col = day % columns;
                    
                    const x = col * CELL_SIZE;
                    const y = row * CELL_SIZE;
                    
                    // 绘制单元格
                    const snapToPixel = (n) => Math.round(n) + 0.5;
                    const cellX = snapToPixel(x);
                    const cellY = snapToPixel(y);
                    const cellSize = Math.floor(CELL_SIZE) - 1;
                    
                    // 绘制单元格背景
                    if (day < validPassed) {
                        // 已过天数（蓝色）
                        offscreenCtx.fillStyle = '#3498db';
                    } else {
                        // 剩余天数（灰色）
                        offscreenCtx.fillStyle = '#7f8c8d';
                    }
                    
                    // 使用路径绘制圆角矩形
                    const radius = isHighQuality ? 2 : 1;
                    offscreenCtx.beginPath();
                    offscreenCtx.moveTo(cellX + radius, cellY);
                    offscreenCtx.lineTo(cellX + cellSize - radius, cellY);
                    offscreenCtx.quadraticCurveTo(cellX + cellSize, cellY, cellX + cellSize, cellY + radius);
                    offscreenCtx.lineTo(cellX + cellSize, cellY + cellSize - radius);
                    offscreenCtx.quadraticCurveTo(cellX + cellSize, cellY + cellSize, cellX + cellSize - radius, cellY + cellSize);
                    offscreenCtx.lineTo(cellX + radius, cellY + cellSize);
                    offscreenCtx.quadraticCurveTo(cellX, cellY + cellSize, cellX, cellY + cellSize - radius);
                    offscreenCtx.lineTo(cellX, cellY + radius);
                    offscreenCtx.quadraticCurveTo(cellX, cellY, cellX + radius, cellY);
                    offscreenCtx.closePath();
                    offscreenCtx.fill();
                    
                    // 每10年添加一个标记
                    if (day % 3650 === 0) {
                        // 绘制十年标记
                        offscreenCtx.fillStyle = '#e74c3c';
                        offscreenCtx.beginPath();
                        offscreenCtx.moveTo(cellX + radius, cellY);
                        offscreenCtx.lineTo(cellX + cellSize - radius, cellY);
                        offscreenCtx.quadraticCurveTo(cellX + cellSize, cellY, cellX + cellSize, cellY + radius);
                        offscreenCtx.lineTo(cellX + cellSize, cellY + cellSize - radius);
                        offscreenCtx.quadraticCurveTo(cellX + cellSize, cellY + cellSize, cellX + cellSize - radius, cellY + cellSize);
                        offscreenCtx.lineTo(cellX + radius, cellY + cellSize);
                        offscreenCtx.quadraticCurveTo(cellX, cellY + cellSize, cellX, cellY + cellSize - radius);
                        offscreenCtx.lineTo(cellX, cellY + radius);
                        offscreenCtx.quadraticCurveTo(cellX, cellY, cellX + radius, cellY);
                        offscreenCtx.closePath();
                        offscreenCtx.fill();
                        
                        // 添加年龄标记
                        const age = day / 365.25;
                        if (CELL_SIZE > 10) {
                            offscreenCtx.fillStyle = '#ffffff';
                            const fontSize = Math.min(CELL_SIZE / 2, 24);
                            offscreenCtx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif`;
                            offscreenCtx.textAlign = 'center';
                            offscreenCtx.textBaseline = 'middle';
                            
                            // 使用整数坐标并添加文本阴影
                            const textX = Math.round(x + CELL_SIZE / 2);
                            const textY = Math.round(y + CELL_SIZE / 2);
                            
                            if (isHighQuality) {
                                offscreenCtx.shadowColor = 'rgba(0, 0, 0, 0.5)';
                                offscreenCtx.shadowBlur = 2;
                                offscreenCtx.shadowOffsetX = 1;
                                offscreenCtx.shadowOffsetY = 1;
                            }
                            
                            offscreenCtx.fillText(Math.floor(age), textX, textY);
                            
                            // 重置阴影
                            if (isHighQuality) {
                                offscreenCtx.shadowColor = 'transparent';
                                offscreenCtx.shadowBlur = 0;
                                offscreenCtx.shadowOffsetX = 0;
                                offscreenCtx.shadowOffsetY = 0;
                            }
                        }
                    }
                    
                    // 标记重要生命节点
                    if (showEvents) {
                        const eventIndex = eventDays.indexOf(day);
                        if (eventIndex !== -1) {
                            const event = lifeEvents[eventIndex];
                            const radius = isHighQuality ? 3 : 1;
                            
                            // 绘制生命节点背景
                            offscreenCtx.fillStyle = event.color;
                            offscreenCtx.beginPath();
                            offscreenCtx.moveTo(cellX + radius, cellY);
                            offscreenCtx.lineTo(cellX + cellSize - radius, cellY);
                            offscreenCtx.quadraticCurveTo(cellX + cellSize, cellY, cellX + cellSize, cellY + radius);
                            offscreenCtx.lineTo(cellX + cellSize, cellY + cellSize - radius);
                            offscreenCtx.quadraticCurveTo(cellX + cellSize, cellY + cellSize, cellX + cellSize - radius, cellY + cellSize);
                            offscreenCtx.lineTo(cellX + radius, cellY + cellSize);
                            offscreenCtx.quadraticCurveTo(cellX, cellY + cellSize, cellX, cellY + cellSize - radius);
                            offscreenCtx.lineTo(cellX, cellY + radius);
                            offscreenCtx.quadraticCurveTo(cellX, cellY, cellX + radius, cellY);
                            offscreenCtx.closePath();
                            offscreenCtx.fill();
                            
                            if (CELL_SIZE > 15) {
                                // 添加事件标记文本
                                offscreenCtx.fillStyle = '#ffffff';
                                const fontSize = Math.min(CELL_SIZE / 3, 16);
                                offscreenCtx.font = `bold ${fontSize}px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif`;
                                offscreenCtx.textAlign = 'center';
                                offscreenCtx.textBaseline = 'middle';
                                
                                const textX = Math.round(x + CELL_SIZE / 2);
                                const textY = Math.round(y + CELL_SIZE / 2);
                                
                                if (isHighQuality) {
                                    offscreenCtx.shadowColor = 'rgba(0, 0, 0, 0.5)';
                                    offscreenCtx.shadowBlur = 1;
                                    offscreenCtx.shadowOffsetX = 1;
                                    offscreenCtx.shadowOffsetY = 1;
                                }
                            
                                offscreenCtx.fillText(event.label, textX, textY);
                            
                                if (isHighQuality) {
                                    offscreenCtx.shadowColor = 'transparent';
                                    offscreenCtx.shadowBlur = 0;
                                    offscreenCtx.shadowOffsetX = 0;
                                    offscreenCtx.shadowOffsetY = 0;
                                }
                            }
                        }
                    }
                }
                
                // 绘制网格线（在填充后绘制，确保线条清晰）
                if (CELL_SIZE > 5 || isHighQuality) {
                    offscreenCtx.strokeStyle = isHighQuality 
                        ? 'rgba(255, 255, 255, 0.2)' 
                        : 'rgba(255, 255, 255, 0.1)';
                    offscreenCtx.lineWidth = isHighQuality ? 2 : 1;
                    
                    // 确保使用整数像素坐标
                    const snapToPixel = (n) => Math.round(n) + 0.5;
                    
                    // 绘制垂直线
                    for (let col = 0; col <= columns; col++) {
                        const x = snapToPixel(col * CELL_SIZE);
                        offscreenCtx.beginPath();
                        offscreenCtx.moveTo(x, 0);
                        offscreenCtx.lineTo(x, rows * CELL_SIZE);
                        offscreenCtx.stroke();
                    }
                    
                    // 绘制水平线
                    for (let row = 0; row <= rows; row++) {
                        const y = snapToPixel(row * CELL_SIZE);
                        offscreenCtx.beginPath();
                        offscreenCtx.moveTo(0, y);
                        offscreenCtx.lineTo(columns * CELL_SIZE, y);
                        offscreenCtx.stroke();
                    }
                    
                    // 在高缩放级别下增加辅助网格线
                    if (isHighQuality && CELL_SIZE > 20) {
                        offscreenCtx.strokeStyle = 'rgba(255, 255, 255, 0.05)';
                        offscreenCtx.lineWidth = 1;
                        
                        // 绘制中间垂直线
                        for (let col = 0; col <= columns; col += 0.5) {
                            if (col % 1 === 0) continue; // 跳过已绘制的主网格线
                            const x = snapToPixel(col * CELL_SIZE);
                            offscreenCtx.beginPath();
                            offscreenCtx.moveTo(x, 0);
                            offscreenCtx.lineTo(x, rows * CELL_SIZE);
                            offscreenCtx.stroke();
                        }
                        
                        // 绘制中间水平线
                        for (let row = 0; row <= rows; row += 0.5) {
                            if (row % 1 === 0) continue; // 跳过已绘制的主网格线
                            const y = snapToPixel(row * CELL_SIZE);
                            offscreenCtx.beginPath();
                            offscreenCtx.moveTo(0, y);
                            offscreenCtx.lineTo(columns * CELL_SIZE, y);
                            offscreenCtx.stroke();
                        }
                    }
                }
                
                                    // 绘制当前进度标记
                                    if (validPassed > 0) {
                                        const currentRow = Math.floor(validPassed / columns);
                                        const currentCol = validPassed % columns;
                        
                                        const x = Math.round(currentCol * CELL_SIZE);
                                        const y = Math.round(currentRow * CELL_SIZE);
                                        const size = CELL_SIZE;
                        
                                        // 绘制高亮边框
                                        offscreenCtx.strokeStyle = '#e74c3c';
                                        offscreenCtx.lineWidth = isHighQuality ? 4 : 3;
                                        offscreenCtx.setLineDash([5, 3]);
                        
                                        offscreenCtx.beginPath();
                                        offscreenCtx.moveTo(x + size * 0.2, y);
                                        offscreenCtx.lineTo(x + size * 0.8, y);
                                        offscreenCtx.moveTo(x + size, y + size * 0.2);
                                        offscreenCtx.lineTo(x + size, y + size * 0.8);
                                        offscreenCtx.moveTo(x + size * 0.8, y + size);
                                        offscreenCtx.lineTo(x + size * 0.2, y + size);
                                        offscreenCtx.moveTo(x, y + size * 0.8);
                                        offscreenCtx.lineTo(x, y + size * 0.2);
                                        offscreenCtx.stroke();
                        
                                        // 重置虚线样式
                                        offscreenCtx.setLineDash([]);
                        
                                        // 在中心添加指示点
                                        offscreenCtx.fillStyle = '#e74c3c';
                                        offscreenCtx.beginPath();
                                        offscreenCtx.arc(x + size/2, y + size/2, isHighQuality ? 4 : 3, 0, Math.PI * 2);
                                        offscreenCtx.fill();
                                    }

                // 将离屏canvas内容复制到主canvas
                try {
                    console.log("准备复制离屏Canvas内容...");
                    
                    // 重置主Canvas的变换
                    ctx.setTransform(1, 0, 0, 1, 0, 0);
                    ctx.scale(pixelRatio, pixelRatio);
                    
                    // 清除并绘制
                    ctx.clearRect(0, 0, displayWidth, displayHeight);
                    ctx.drawImage(offscreenCanvas, 0, 0);
                    
                    console.log("离屏Canvas内容已复制");
                } 
                catch (error) {
                    console.error("绘制失败:", error);
                    // 回退到直接在主Canvas上绘制
                    ctx.clearRect(0, 0, canvas.width, canvas.height);
                    drawGridDirectly(passed);
                } 
                finally {
                    ctx.restore();
                    
                    // 强制重绘以确保显示更新
                    requestAnimationFrame(() => {
                        canvas.style.transform = canvas.style.transform;
                        console.log("强制重绘完成");
                    });
                }
            };
            
            // 直接在主Canvas上绘制的回退方法
            function drawGridDirectly(passed) {
                console.log("使用回退方法绘制网格...");
                const { pixelRatio, displayWidth, displayHeight } = calculateOptimalSize();
                
                ctx.save();
                ctx.scale(pixelRatio, pixelRatio);
                ctx.clearRect(0, 0, displayWidth, displayHeight);
                
                // 简化的绘制逻辑
                const { rows, columns } = calculateOptimalSize();
                const validPassed = Math.min(Math.max(passed, 0), daysInLife);
                
                // 绘制背景
                ctx.fillStyle = 'rgba(44, 62, 80, 0.9)';
                ctx.fillRect(0, 0, displayWidth, displayHeight);
                
                // 绘制已过天数
                ctx.fillStyle = '#3498db';
                for (let day = 0; day < validPassed; day++) {
                    const row = Math.floor(day / columns);
                    const col = day % columns;
                    const x = col * CELL_SIZE;
                    const y = row * CELL_SIZE;
                    ctx.fillRect(x + 1, y + 1, CELL_SIZE - 2, CELL_SIZE - 2);
                }
                
                // 绘制剩余天数
                ctx.fillStyle = '#7f8c8d';
                for (let day = validPassed; day < daysInLife; day++) {
                    const row = Math.floor(day / columns);
                    const col = day % columns;
                    const x = col * CELL_SIZE;
                    const y = row * CELL_SIZE;
                    ctx.fillRect(x + 1, y + 1, CELL_SIZE - 2, CELL_SIZE - 2);
                }
                
                ctx.restore();
            }

            // 移除旧的updateTooltip函数

            // 视图控制变量
            let zoomLevel = 1;
            const zoomStep = 0.1;
            const minZoom = 0.2;
            const maxZoom = 5;
            let panX = 0;
            let panY = 0;
            let isDragging = false;
            let startDragX = 0;
            let startDragY = 0;
            let startPanX = 0;
            let startPanY = 0;
            
            const canvasWrapper = document.getElementById('canvasWrapper');
            
            // 应用变换（缩放和平移）
            function applyTransform() {
                canvasWrapper.style.transform = `translate(${panX}px, ${panY}px) scale(${zoomLevel})`;
            }
            
            // 重置视图
            function resetView(animate = true) {
                const container = document.querySelector('.canvas-container');
                
                if (animate) {
                    canvasWrapper.style.transition = 'transform 0.5s ease-out';
                    setTimeout(() => {
                        canvasWrapper.style.transition = 'transform 0.1s ease-out';
                    }, 500);
                }
                
                zoomLevel = 1;
                
                // 计算居中位置
                const { width, height } = calculateOptimalSize();
                const containerWidth = container.clientWidth;
                const containerHeight = container.clientHeight;
                
                panX = (containerWidth - width) / 2;
                panY = (containerHeight - height) / 2;
                
                applyTransform();
            }
            
            // 缩放到特定点
            function zoomToPoint(x, y, factor) {
                // 保存鼠标相对于画布的位置比例
                const containerRect = document.querySelector('.canvas-container').getBoundingClientRect();
                const mouseX = x - containerRect.left;
                const mouseY = y - containerRect.top;
                
                // 计算鼠标在缩放前的画布坐标
                const oldMouseCanvasX = (mouseX - panX) / zoomLevel;
                const oldMouseCanvasY = (mouseY - panY) / zoomLevel;
                
                // 应用缩放
                zoomLevel *= factor;
                zoomLevel = Math.max(minZoom, Math.min(maxZoom, zoomLevel));
                
                // 计算鼠标在缩放后的画布坐标
                const newMouseCanvasX = oldMouseCanvasX * zoomLevel;
                const newMouseCanvasY = oldMouseCanvasY * zoomLevel;
                
                // 调整平移以保持鼠标位置不变
                panX = mouseX - newMouseCanvasX;
                panY = mouseY - newMouseCanvasY;
                
                applyTransform();
            }

            // 主更新函数
            const updateGrid = () => {
                if (!validateInput()) return;

                let passed = 0;
                if (inputType.value === 'birthdate') {
                    const birthDate = birthdateInput.value;
                    if (!birthDate) return;
                    passed = calculatePassedDays(birthDate);
                } else {
                    const age = ageInput.value;
                    if (!age) return;
                    passed = calculateValidDays('age', age);
                }

                passed = Math.max(0, Math.min(passed, daysInLife));
                
                // 安全更新统计信息
                const totalElement = document.getElementById('total');
                const passedElement = document.getElementById('passed');
                const remainingElement = document.getElementById('remaining');
                
                if (totalElement) totalElement.textContent = daysInLife.toLocaleString();
                if (passedElement) passedElement.textContent = passed.toLocaleString();
                if (remainingElement) remainingElement.textContent = (daysInLife - passed).toLocaleString();
                
                if (!totalElement || !passedElement || !remainingElement) {
                    console.warn('统计元素未找到，无法更新显示');
                }
                
                console.log("更新网格，已过天数:", passed);
                
                // 重置变换状态
                zoomLevel = 1;
                
                // 重新初始化画布
                initCanvas();
                
                // 确保画布完全加载后再绘制
                setTimeout(() => {
                    console.log("绘制网格...");
                    drawGrid(passed);
                    
                    // 重置视图并滚动到当前进度位置
                    const { columns } = calculateOptimalSize();
                    const currentRow = Math.floor(passed / columns);
                    const currentCol = passed % columns;
                    
                    // 计算目标位置（当前进度的中心点）
                    const container = document.querySelector('.canvas-container');
                    const targetX = currentCol * CELL_SIZE;
                    const targetY = currentRow * CELL_SIZE;
                    
                    console.log("居中到位置:", targetX, targetY);
                    
                    // 计算居中位置
                    const { displayWidth, displayHeight } = calculateOptimalSize();
                    panX = (container.clientWidth - displayWidth) / 2;
                    panY = (container.clientHeight - displayHeight) / 2;
                    
                    // 调整到目标位置
                    if (passed > 0) {
                        panX = panX - targetX + container.clientWidth / 3;
                        panY = panY - targetY + container.clientHeight / 3;
                    }
                    
                    console.log("应用变换:", panX, panY, zoomLevel);
                    
                    // 使用动画过渡到目标位置
                    canvasWrapper.style.transition = 'transform 0.8s ease-out';
                    applyTransform();
                    
                    // 恢复正常的过渡时间
                    setTimeout(() => {
                        canvasWrapper.style.transition = 'transform 0.1s ease-out';
                    }, 800);
                }, 100);
            };

            // 更新tooltip位置计算
            const updateTooltip = (e) => {
                const rect = canvas.getBoundingClientRect();
                const containerRect = document.querySelector('.canvas-container').getBoundingClientRect();
                
                // 计算鼠标在画布上的实际位置（考虑缩放和平移）
                const mouseX = (e.clientX - rect.left - panX) / zoomLevel;
                const mouseY = (e.clientY - rect.top - panY) / zoomLevel;
                
                // 获取网格布局信息
                const { columns } = calculateOptimalSize();
                
                // 计算当前鼠标位置对应的行列
                const col = Math.floor(mouseX / CELL_SIZE);
                const row = Math.floor(mouseY / CELL_SIZE);
                
                // 计算对应的天数
                const day = row * columns + col;
                
                if (day < 0 || day >= daysInLife) {
                    tooltip.style.opacity = '0';
                    return;
                }

                const years = ((day + 1) / 365.25).toFixed(2);
                const percentage = ((day + 1) / daysInLife * 100).toFixed(2);
                
                // 计算年月日
                const ageYears = Math.floor(years);
                const ageMonths = Math.floor((years - ageYears) * 12);
                const ageDays = Math.floor((years - ageYears - ageMonths / 12) * 365.25);

                // 检查是否是重要生命节点
                let eventInfo = '';
                const showEvents = document.getElementById('showEvents').checked;
                
                if (showEvents) {
                    // 查找最接近的生命节点
                    const event = lifeEvents.find(e => Math.abs(e.age - ageYears) < 0.1);
                    
                    if (event) {
                        eventInfo = `<div style="color:${event.color};font-weight:bold;margin-top:5px;">
                            ${event.age}岁 - ${event.label}
                            <div style="font-weight:normal;font-size:12px;margin-top:3px;">
                                ${event.description}
                            </div>
                        </div>`;
                    }
                }

                // 计算剩余寿命
                const remainingYears = ((daysInLife - day - 1) / 365.25).toFixed(2);

                // 计算tooltip的位置，确保不会超出容器边界
                let tooltipX = e.clientX;
                let tooltipY = e.clientY - 10;
                
                const tooltipWidth = 200; // 估计的tooltip宽度
                const tooltipHeight = 150; // 估计的tooltip高度
                
                // 确保tooltip不会超出右边界
                if (tooltipX + tooltipWidth > containerRect.right) {
                    tooltipX = containerRect.right - tooltipWidth - 10;
                }
                
                // 确保tooltip不会超出底部边界
                if (tooltipY + tooltipHeight > containerRect.bottom) {
                    tooltipY = containerRect.bottom - tooltipHeight - 10;
                }

                tooltip.style.opacity = '1';
                tooltip.style.left = `${tooltipX}px`;
                tooltip.style.top = `${tooltipY}px`;
                tooltip.innerHTML = `
                    <div style="border-bottom:1px solid rgba(255,255,255,0.2);padding-bottom:5px;margin-bottom:5px;">
                        第 ${(day + 1).toLocaleString()} 天
                    </div>
                    年龄: ${years} 岁 (${ageYears}年${ageMonths}个月${ageDays}天)<br>
                    剩余: ${remainingYears} 岁<br>
                    进度: ${percentage}%
                    ${eventInfo}`;
            };

            // 键盘导航支持
            canvas.addEventListener('keydown', (e) => {
                const container = canvas.parentElement;
                const scrollAmount = 100;
                
                if (e.key === 'ArrowLeft') {
                    container.scrollLeft -= scrollAmount;
                    e.preventDefault();
                } else if (e.key === 'ArrowRight') {
                    container.scrollLeft += scrollAmount;
                    e.preventDefault();
                } else if (e.key === 'ArrowUp') {
                    container.scrollTop -= scrollAmount;
                    e.preventDefault();
                } else if (e.key === 'ArrowDown') {
                    container.scrollTop += scrollAmount;
                    e.preventDefault();
                }
            });

            // 缩放事件处理
            document.getElementById('zoomIn').addEventListener('click', () => {
                if (zoomLevel < maxZoom) {
                    zoomLevel += zoomStep;
                    applyZoom();
                }
            });
            
            document.getElementById('zoomOut').addEventListener('click', () => {
                if (zoomLevel > minZoom) {
                    zoomLevel -= zoomStep;
                    applyZoom();
                }
            });
            
            document.getElementById('zoomReset').addEventListener('click', () => {
                zoomLevel = 1;
                applyZoom();
            });

            // 拖动事件处理
            const container = document.querySelector('.canvas-container');
            
            container.addEventListener('mousedown', (e) => {
                if (e.button === 0) { // 只响应左键
                    isDragging = true;
                    startDragX = e.clientX;
                    startDragY = e.clientY;
                    startPanX = panX;
                    startPanY = panY;
                    container.style.cursor = 'grabbing';
                    e.preventDefault();
                }
            });
            
            document.addEventListener('mousemove', (e) => {
                if (isDragging) {
                    const dx = e.clientX - startDragX;
                    const dy = e.clientY - startDragY;
                    panX = startPanX + dx;
                    panY = startPanY + dy;
                    applyTransform();
                    e.preventDefault();
                }
                
                // 更新tooltip位置
                if (e.target === canvas) {
                    updateTooltip(e);
                } else {
                    tooltip.style.opacity = '0';
                }
            });
            
            document.addEventListener('mouseup', () => {
                if (isDragging) {
                    isDragging = false;
                    container.style.cursor = 'grab';
                }
            });
            
            // 防止拖动时选择文本
            container.addEventListener('selectstart', (e) => {
                if (isDragging) e.preventDefault();
            });
            
            // 鼠标滚轮缩放
            container.addEventListener('wheel', (e) => {
                e.preventDefault();
                
                const factor = e.deltaY < 0 ? 1 + zoomStep : 1 - zoomStep;
                zoomToPoint(e.clientX, e.clientY, factor);
            }, { passive: false });
            
            // 双击重置视图
            container.addEventListener('dblclick', (e) => {
                e.preventDefault();
                resetView();
            });
            
            // 缩放按钮事件
            document.getElementById('zoomIn').addEventListener('click', () => {
                const containerRect = container.getBoundingClientRect();
                const centerX = containerRect.left + containerRect.width / 2;
                const centerY = containerRect.top + containerRect.height / 2;
                zoomToPoint(centerX, centerY, 1 + zoomStep);
            });
            
            document.getElementById('zoomOut').addEventListener('click', () => {
                const containerRect = container.getBoundingClientRect();
                const centerX = containerRect.left + containerRect.width / 2;
                const centerY = containerRect.top + containerRect.height / 2;
                zoomToPoint(centerX, centerY, 1 - zoomStep);
            });
            
            document.getElementById('zoomReset').addEventListener('click', () => {
                resetView();
            });
            
            // 触摸支持
            container.addEventListener('touchstart', (e) => {
                if (e.touches.length === 1) {
                    isDragging = true;
                    startDragX = e.touches[0].clientX;
                    startDragY = e.touches[0].clientY;
                    startPanX = panX;
                    startPanY = panY;
                    e.preventDefault();
                }
            }, { passive: false });
            
            container.addEventListener('touchmove', (e) => {
                if (isDragging && e.touches.length === 1) {
                    const dx = e.touches[0].clientX - startDragX;
                    const dy = e.touches[0].clientY - startDragY;
                    panX = startPanX + dx;
                    panY = startPanY + dy;
                    applyTransform();
                    e.preventDefault();
                }
            }, { passive: false });
            
            container.addEventListener('touchend', () => {
                isDragging = false;
            });
            
            // 其他事件绑定
            inputType.addEventListener('change', updateInputVisibility);
            document.getElementById('generateBtn').addEventListener('click', updateGrid);
            
            canvas.addEventListener('mouseleave', () => {
                tooltip.style.opacity = '0';
            });

            // 图例控制
            const legend = document.getElementById('legend');
            const showLegendBtn = document.getElementById('showLegendBtn');
            const closeLegendBtn = document.getElementById('closeLegend');
            const showEventsCheckbox = document.getElementById('showEvents');

            // 显示/隐藏图例
            function toggleLegend() {
                if (legend.style.display === 'none' || !legend.style.display) {
                    legend.style.display = 'block';
                    generateLegend();
                } else {
                    legend.style.display = 'none';
                }
            }

            // 重新绘制带有生命节点的网格
            function redrawWithEvents() {
                try {
                    const passedElement = document.getElementById('passed');
                    if (!passedElement) {
                        console.warn('passed元素未找到，跳过重绘');
                        return;
                    }
                    const passed = parseInt(passedElement.textContent.replace(/,/g, '')) || 0;
                    drawGrid(passed);
                } catch (e) {
                    console.error('重绘事件时出错:', e);
                }
            }

            // 事件监听器
            showLegendBtn.addEventListener('click', toggleLegend);
            closeLegendBtn.addEventListener('click', toggleLegend);
            showEventsCheckbox.addEventListener('change', redrawWithEvents);

            // 点击图例外部关闭图例
            document.addEventListener('click', (e) => {
                if (legend.style.display === 'block' && 
                    !legend.contains(e.target) && 
                    e.target !== showLegendBtn) {
                    legend.style.display = 'none';
                }
            });

            // 初始化函数
            function initialize() {
                console.log("开始初始化...");
                
                updateInputVisibility();
                
                // 确保DOM完全加载
                setTimeout(() => {
                    try {
                        initCanvas();
                        generateLegend();
                        
                        // 初始化视图位置
                        resetView(false);
                        
                        // 设置canvas可聚焦以支持键盘导航
                        canvas.tabIndex = 0;
                        
                        // 添加渐入动画效果
                        container.style.opacity = '0';
                        requestAnimationFrame(() => {
                            container.style.transition = 'opacity 0.5s ease-out';
                            container.style.opacity = '1';
                            console.log("初始化完成");
                        });
                        
                        // 强制绘制初始网格
                        setTimeout(() => {
                            const passed = parseInt(document.getElementById('passed').textContent.replace(/,/g, '')) || 0;
                            drawGrid(passed);
                            console.log("初始网格绘制完成");
                        }, 100);
                    } catch (error) {
                        console.error("初始化失败:", error);
                    }
                }, 100);
            }

            // 窗口调整大小处理
            let resizeTimeout;
            window.addEventListener('resize', () => {
                // 防抖处理
                clearTimeout(resizeTimeout);
                resizeTimeout = setTimeout(() => {
                    initCanvas(); // 这会自动调用drawGrid
                }, 100);
            });

            // 应用缩放和平移变换
            function applyZoom() {
                console.log("应用缩放，当前缩放级别:", zoomLevel);
                applyTransform();
                
                // 获取当前进度并重绘网格
                const passed = parseInt(document.getElementById('passed').textContent.replace(/,/g, '')) || 0;
                console.log("重绘网格，已过天数:", passed);
                drawGrid(passed);
            }

            // 键盘快捷键支持
            document.addEventListener('keydown', (e) => {
                if (e.key === 'l' && e.ctrlKey) { // Ctrl+L 显示/隐藏图例
                    e.preventDefault();
                    toggleLegend();
                } else if (e.key === 'e' && e.ctrlKey) { // Ctrl+E 显示/隐藏生命节点
                    e.preventDefault();
                    showEventsCheckbox.checked = !showEventsCheckbox.checked;
                    redrawWithEvents();
                } else if (e.key === '0' && e.ctrlKey) { // Ctrl+0 重置视图
                    e.preventDefault();
                    resetView();
                } else if (e.key === 'Home') { // Home 键跳转到开始
                    e.preventDefault();
                    const container = document.querySelector('.canvas-container');
                    panX = (container.clientWidth - canvas.width) / 2;
                    panY = (container.clientHeight - canvas.height) / 2;
                    zoomLevel = 1;
                    canvasWrapper.style.transition = 'transform 0.5s ease-out';
                    applyTransform();
                    setTimeout(() => {
                        canvasWrapper.style.transition = 'transform 0.1s ease-out';
                    }, 500);
                }
            });

            // 更新UI语言
            function updateLanguageUI() {
                const lang = translations[currentLanguage];
                
                // 安全更新函数
                function safeUpdate(id, property, value) {
                    try {
                        const element = document.getElementById(id);
                        if (element && element[property] !== undefined) {
                            element[property] = value;
                            return true;
                        }
                        console.warn(`元素 ${id} 或属性 ${property} 不存在`);
                        return false;
                    } catch (e) {
                        console.error(`更新 ${id}.${property} 时出错:`, e);
                        return false;
                    }
                }
                
                // 更新标题
                safeUpdate('headerTitle', 'textContent', lang.header);
                
                // 更新语言切换按钮
                safeUpdate('toggleLanguage', 'textContent', lang.toggleLanguage);
                
                // 更新输入选项
                const inputTypeSelect = document.getElementById('inputType');
                if (inputTypeSelect) {
                    inputTypeSelect.innerHTML = '';
                    lang.inputTypeOptions.forEach(option => {
                        const opt = document.createElement('option');
                        opt.value = option.value;
                        opt.textContent = option.text;
                        inputTypeSelect.appendChild(opt);
                    });
                }
                
                // 更新年龄输入框占位符
                safeUpdate('ageInput', 'placeholder', lang.agePlaceholder);
                
                // 更新按钮文本
                safeUpdate('generateBtn', 'textContent', lang.generateBtn);
                
                // 更新复选框标签
                const showEventsLabel = document.querySelector('label[for="showEvents"]');
                if (showEventsLabel) showEventsLabel.textContent = lang.showEvents;
                safeUpdate('showLegendBtn', 'textContent', lang.showLegend);
                
                // 安全更新复选框状态
                safeUpdate('showEvents', 'checked', document.getElementById('showEvents')?.checked || false);
                safeUpdate('showLegend', 'checked', document.getElementById('showLegend')?.checked || false);
                
                // 安全更新统计标签
                try {
                    const statElements = document.querySelectorAll('.stats div');
                    const statValues = [
                        document.getElementById('total')?.textContent || '0',
                        document.getElementById('passed')?.textContent || '0', 
                        document.getElementById('remaining')?.textContent || '0'
                    ];
                    
                    statElements.forEach((element, index) => {
                        if (element && lang.stats[index]) {
                            element.textContent = `${lang.stats[index]}: ${statValues[index]}`;
                        }
                    });
                } catch (e) {
                    console.error('更新统计信息时出错:', e);
                }
                
                // 更新图例
                console.log('更新图例内容...');
                const legendContainer = document.getElementById('legendContainer');
                if (legendContainer) {
                    // 更新图例标题
                    const legendTitle = legendContainer.querySelector('h3');
                    if (legendTitle) legendTitle.textContent = lang.legendTitle;
                    
                    // 完全重建图例内容
                    const legendContent = legendContainer.querySelector('.legend-content');
                    if (legendContent) {
                        legendContent.innerHTML = '';
                        lang.legendItems.forEach(item => {
                            const itemDiv = document.createElement('div');
                            itemDiv.className = 'legend-item';
                            itemDiv.innerHTML = `
                                <span>${item.label}</span>
                                <p>${item.description}</p>
                            `;
                            legendContent.appendChild(itemDiv);
                        });
                    }
                    
                    console.log('图例内容已更新');
                }
                
                // 更新生命事件描述
                lifeEvents.forEach((event, index) => {
                    event.label = lang.lifeEvents[index].label;
                    event.description = lang.lifeEvents[index].description;
                });
                
                // 安全强制重新渲染图例和事件
                const showEventsEl = document.getElementById('showEvents');
                const showLegendEl = document.getElementById('showLegend');
                if (showEventsEl && showEventsEl.checked) {
                    redrawWithEvents();
                }
                if (showLegendEl && showLegendEl.checked) {
                    toggleLegend();
                }
                
                // 重新生成图例
                generateLegend();
                
                // 重新绘制网格以更新事件标记
                const passed = parseInt(document.getElementById('passed')?.textContent.replace(/,/g, '') || '0');
                drawGrid(passed);
            }

            // 切换语言函数
            function toggleLanguage() {
                currentLanguage = currentLanguage === 'zh' ? 'en' : 'zh';
                updateLanguageUI();
            }

            // 添加语言切换事件监听
            document.getElementById('toggleLanguage').addEventListener('click', toggleLanguage);

            // 安全初始化UI语言
            function safeInitialize() {
                try {
                    // 确保关键DOM元素存在
                    const requiredElements = [
                        'headerTitle', 'toggleLanguage', 'inputType', 
                        'ageInput', 'generateBtn', 'showEvents', 
                        'showLegendBtn', 'passed', 'total', 'remaining'
                    ];
                    
                    const allElementsExist = requiredElements.every(id => {
                        const element = document.getElementById(id);
                        if (!element) {
                            console.warn(`元素 ${id} 未找到`);
                            return false;
                        }
                        // 检查元素是否可访问
                        if (element.textContent === undefined && element.value === undefined) {
                            console.warn(`元素 ${id} 不可访问`);
                            return false;
                        }
                        return true;
                    });
                    
                    if (!allElementsExist) {
                        console.error('关键DOM元素缺失或不可访问，延迟重试');
                        setTimeout(safeInitialize, 100);
                        return;
                    }

                    // 确保元素内容已加载
                    const readyCheck = () => {
                        try {
                            const testElement = document.getElementById('headerTitle');
                            if (testElement && testElement.textContent !== null) {
                                if (document.readyState === 'complete') {
                                    updateLanguageUI();
                                    initialize();
                                } else {
                                    window.addEventListener('load', () => {
                                        updateLanguageUI();
                                        initialize();
                                    });
                                }
                            } else {
                                setTimeout(readyCheck, 50);
                            }
                        } catch (e) {
                            console.error('准备检查失败:', e);
                            setTimeout(safeInitialize, 100);
                        }
                    };
                    
                    readyCheck();
                } catch (e) {
                    console.error('初始化失败:', e);
                    setTimeout(safeInitialize, 100);
                }
            }
            
            safeInitialize();
        });
    </script>
</body>
</html>